package net._708s.logmanager.service;

import net._708s.logmanager.domain.Log;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * index log
 * @author ajian
 * 
 */
public class IndexService {
	public static IndexWriter initIndex(String indexPath){
		try{
			Directory dir = FSDirectory.open(new File(indexPath));
			Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_40);
			IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_40,analyzer);
			iwc.setOpenMode(OpenMode.CREATE_OR_APPEND);
			IndexWriter writer;
			writer = new IndexWriter(dir, iwc);
			return writer;
		}catch(Exception e){
			return null;
		}
	}
	
	public String index(Log one,String indexPath){
		List<Log> logList = new ArrayList<Log>();
		logList.add(one);
		return index(logList,indexPath);
	}
	
	public String index(List<Log> logList,String indexPath){
		IndexWriter writer = initIndex(indexPath);
		if(null != writer){
			String index_message = indexDocs(writer,logList);
			if("".equals(index_message)){
				return "{\"error_code\":1,\"message\":\"index force success,but index nothing.\"}";
			}
			return "{\"error_code\":0,\"message\":\""+index_message+"\"}";
		}else{
			return "{\"error_code\":2,\"message\":\"index error because of null writer.\"}";
		}
	}
	
	
	/** Index all text files under a directory. */
	public static void main(String[] args) {
		/**
		 * @param id
		 * @param type
		 * @param message
		 * @param source
		 * @param date
		 */
		Log log1 = new Log("001","info","log  success!","index",new Date());
		Log log2 = new Log("002","error","log  error!","index",new Date());
		Log log3 = new Log("003","warning","log  warning!","index",new Date());
		Log log4 = new Log("004","debug","log debug !","index",new Date());
		Log log5 = new Log("005","info","log info success,it's a beautiful day!","index",new Date());
		List<Log> logList = new ArrayList<Log>();
		logList.add(log1);
		logList.add(log2);
		logList.add(log3);
		logList.add(log4);
		logList.add(log5);
//		indexService.index(logList,indexPath);
	}

	/**
	 * @param writer
	 *            Writer to the index where the given file/dir info will be
	 *            stored
	 * @param file
	 *            The file to index, or the directory to recurse into to find
	 *            files to index
	 * @throws IOException
	 *             If there is a low-level I/O error
	 */
	public String indexDocs(IndexWriter writer, List<Log> logList) {
		String index_message = "";
		try {
			for(Log log : logList){
				if(log.legal()){
					Document doc = new Document();
					Field id = new StringField("id", log.getId(),Field.Store.YES);
					Field type = new StringField("type", log.getType(),Field.Store.YES);
					Field date = new LongField("date",log.getDate().getTime(), Field.Store.YES);
					Field source = new StringField("source", log.getSource(),Field.Store.YES);
					Field message = new TextField("message", log.getMessage(),Field.Store.YES);           
					doc.add(id);
					doc.add(type);
					doc.add(date);
					doc.add(source);
					doc.add(message);
					writer.deleteDocuments(new Term("id", log.getId()));
					writer.addDocument(doc);
					index_message = index_message + " |log[id:"+log.getId()+"]index success.";
				}
			}
			
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try {
				writer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return index_message;
	}
	
	public String delete(Log one,String indexPath){
		List<Log> logList = new ArrayList<Log>();
		logList.add(one);
		return delete(logList,indexPath);
	}
	
	public String delete(List<Log> logList,String indexPath){
		IndexWriter writer = initIndex(indexPath);
		if(null != writer){
			String delete_message = deleteDocs(writer,logList);
			if("".equals(delete_message)){
				return "{\"error_code\":1,\"message\":\"delete force success,but delete nothing.\"}";
			}
			return "{\"error_code\":0,\"message\":\""+delete_message+"\"}";
		}else{
			return "{\"error_code\":2,\"message\":\"delete error because of null writer.\"}";
		}
	}
	
	public String deleteDocs(IndexWriter writer, List<Log> logList){
		String delete_message = "";
		List<Term> termList = new ArrayList<Term>();
		
		try {
			for(Log log : logList){
				if(log.legal()){
					termList.add(new Term("id",log.getId()));
					delete_message = delete_message + " |log[id:"+log.getId()+"] should be deleted.";
				}
			}
			Term[] termArray = new Term[termList.size()];
			writer.deleteDocuments(termList.toArray(termArray));
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try {
				writer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return delete_message;
	}
}